<template>
  <view>
    <view class="fixed-bg"></view>
    <view class="make-card-containerm">
      <uni-nav-bar left-icon="back" @clickLeft="gotoBack" color="#fff" status-bar="true" :border="false"
        background-color="transparent" left-width="20px">
        <view style="line-height: 44px;">
          <navigator url="/pages/index/index" open-type="switchTab">
            <uni-icons type="home-filled" color="#fff" size="22"></uni-icons>
          </navigator>
        </view>
      </uni-nav-bar>
      <view class="content">
        <view class="card-edit-container" :class="{'showMessage':cardStatus}">
          <view v-if="cardStatus == 1 || isComplete " class="op-content">
            <text @click="onPreview()">预览</text>
            <text @click="gotoBack()">取消</text>
          </view>
          <view class="upload-img-container car-item" @click="nextStep" :style="{'height':height}">
            <view class="upload-img" @click.stop="chooseImage" v-if="cliperImg == ''">
              <uni-icons type="plusempty" size="40" color="#4bc7bd"></uni-icons>
              <view>请添加一张图片</view>
            </view>
            <image :src="cliperImg" mode="widthFix" v-else style="width: 100%;height: 100%;"></image>
            <view class="record-btn" @click="playBgm" :style="style" :class="{'recording':isPlaying}"
              v-if="postcardId && defaultSoundUrl">
              <view>
                <image src="../../static/shiting.png" mode="widthFix" v-if="!isPlaying"></image>
                <image src="../../static/zanting.png" mode="widthFix" v-else></image>
              </view>
            </view>
          </view>
          <view class="enter-message-container car-item">
            <view class="message-bg">
              <view class="input-container">
                <input type="text" placeholder="填写TA的称呼" :disabled="isComplete" v-model="sending"
                  placeholder-style="color:#6cd7cd" />
              </view>
              <view class="message-content-container">
                <view class="texture-container" style="position: relative;">
                  <!-- <view style="display: flex;font-size: 32rpx;color: black;gap: 20px;">
                    <view @click="()=>{if(!isComplete){inputType = 1}}" style="flex:1;text-align:center"
                      :class="{'active':inputType==1}">键盘输入
                    </view>
                    <view @click="()=>{if(!isComplete){inputType = 0}}" style="flex:1;text-align:center"
                      :class="{'active':inputType==0}">手写输入
                    </view>
                  </view> -->
                  <view style="position: relative;">
                    <textarea v-model="content" maxlength="120" @input="checkSpecialChars" :auto-focus="false"
                      :disabled="isComplete" />
                    <view class="cavnas-container" :class="{'show':(inputType == 0 || showCanvas == true)}">
                      <canvas canvas-id="signature" id="signature" class="write-canvas" type="2d"
                        style="width:100%;height: 100%;" @touchstart="touchstart" @touchmove="touchmove"
                        @touchend="touchend"></canvas>
                    </view>
                  </view>

                </view>
                <image :src="signatureImg" mode="widthFix" v-if="signatureImg" style="width: 100%;"></image>


              </view>
              <view class="input-container">
                <input type="text" v-model="sign" :disabled="isComplete" placeholder="填写你的名字"
                  placeholder-style="color:#6cd7cd" />
              </view>
            </view>
            <view class="record mt20" style="display: flex;justify-content: space-between;">
              <view @click="getRandomContent"><uni-icons type="reload" color="#4bc7bd"></uni-icons>生成一条祝福语</view>
              <view v-if="voicePath" style="display: flex;align-items: center;gap: 20rpx;">

                <view @click="()=>{if(!isComplete){$refs.recordPopup.open()}}">
                  <uni-icons type="refreshempty" color="#6cd7cd"></uni-icons>重录
                </view>
              </view>
              <view v-else @click="()=>{if(!isComplete){showRecordPop()}}"
                style="display: flex;align-items: center;gap:10rpx;justify-content: flex-end;">
                <image src="../../static/huatong.png" mode="widthFix"
                  style="filter:opacity(0.4) drop-shadow(0 0 0 #6cd7cd);width:40rpx">
                </image>
                录一段语音给他
              </view>
            </view>
            <voice-play :vocie-src="voicePath" height="60rpx" style="margin-top: 30rpx;" v-if="voicePath"></voice-play>
          </view>

        </view>
        <view style="width: 557rpx;">
          <block v-if="!isComplete">
            <view v-if="cardStatus == 1">
              <label>
                <checkbox-group @change="onCheckboxChnage" style="display: inline-block;">
                  <checkbox :checked="isOpen" style="transform: scale(0.7);vertical-align: middle;" />
                </checkbox-group>

                <text>同步到广场，让大家都看到</text>
              </label>
            </view>
            <view class="keep-make" @click="nextStep" :class="{disabled:cardStatus == 0 && uploadImg == ''}">
              {{cardStatus == 1 ? '制作完成' : '继续制作' }}
            </view>

          </block>
          <block v-else>
            <view class="flex gap30">
              <button type="default" hover-class="is-hover" style="width:40%" @click="gotoUrl">立即分享</button>
              <button type="default" hover-class="is-hover" style="width:40%" @click="showDetail">查看</button>
            </view>
          </block>
        </view>
      </view>

    </view>
    <l-clipper is-lock-height is-lock-width :image-url="uploadImg" :width="imageWidth" :height="imageHeight"
      :scale-ratio="scaleRatio" @success="cliperSuccess" v-if="showClipper" @cancel="showClipper = false"></l-clipper>
    <uni-popup ref="recordPopup" type="bottom" :safe-area="false" :mask-click="false">
      <view class="record-container">
        <view class="close-icon" @click="closeRecordPopup">
          <uni-icons type="close" size="40" color="#4bc7bd"></uni-icons>
        </view>
        <view class="side-btn" @click="reRecord" v-show="recordStatus == 2 || recordStatus == 3">
          <image src="../../static/chonglu.png" mode="widthFix"></image>
          <view>重录</view>
        </view>
        <view class="record-btn-container">
          <view class="record-btn" @click="handleRecordBtn" :style="style" :class="{'recording':recordStatus == 1}">
            <view>
              <image src="../../static/luyin.png" mode="widthFix" v-if="recordStatus == 0"></image>
              <image src="../../static/luyinzhong.png" mode="widthFix" v-if="recordStatus == 1"></image>
              <image src="../../static/shiting.png" mode="widthFix" v-if="recordStatus == 2"></image>
              <image src="../../static/zanting.png" mode="widthFix" v-if="recordStatus == 3"></image>
            </view>
          </view>
          <view>{{['开始录音','点击完成','点击试听','结束试听'][recordStatus]}}</view>
        </view>
        <view class="side-btn" @click="useVoice" v-show="recordStatus == 2 || recordStatus == 3">
          <image src="../../static/shiyong.png" mode="widthFix"></image>
          <view>使用</view>
        </view>
      </view>
    </uni-popup>
    <privacy-popup ref="privacy" :privacyContractName="privacyContractName"></privacy-popup>
    <uni-popup ref="previewPop" type="center">
      <view class="preview-content">
        <image :src="cliperImg" mode="widthFix"></image>
        <image :src="letterImage" mode="widthFix"></image>
        <view class="keep-make" @click="handleCardComplete">
          制作完成
        </view>

      </view>
    </uni-popup>
  </view>

</template>

<script>
  const imageAspectRatio = 3 / 2; //宽高比
  import {
    uploadQ,
    uploadSound
  } from '@/apis/upload';
  import {
    addPostCard,
    getPostcardList,
    updateUserPostcard,
    createCustomPostcard,
    checkMsg,
    createReplyPostcard,
    getContent
  } from '@/apis/postcard.js'
  import {
    getQueryVarible
  } from '@/common/utils.js'
  const recorderManager = uni.getRecorderManager();
  const innerAudioContext = uni.createInnerAudioContext();
  const CARD_STATUS = {
    UPLOAD_IMAGE: 0,
    ENTER_MESSAGE: 1,
  }
  const RECORD_STATUS = {
    START_RECORD: 0,
    FINISH_RECORD: 1,
    START_TEST: 3,
    END_TEST: 4
  }
  export default {
    data() {
      return {
        sending: '',
        sign: '',
        cliperImg: '',
        signatureImg: '',
        content: '',
        isOpen: 0,
        voicePath: '',
        uploadImg: '',
        cardStatus: CARD_STATUS.UPLOAD_IMAGE,
        recordStatus: 0,
        style: `--percent:0`,
        showClipper: false,
        isPlaying: false,
        postcardId: "",
        isComplete: false,
        showTexture: false,
        defaultSoundUrl: '',
        modelcardId: '',
        height: '180px',
        showSignature: false,
        inputType: 1,
        scaleRatio: 3,
        imageWidth: 0,
        imageHeight: 0,
        privacyContractName: '',
        showCanvas: false,
        letterImage: "",
      };
    },
    watch: {
      inputType(newV, oldV) {
        if (newV == 1) {
          this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
          this.writeImage = null;
        }
      }
    },
    onLoad(options) {
      const _this = this;
      const userinfo = uni.getStorageSync('userinfo');
      this.userId = userinfo?.userId;
      this.modelcardId = options.modelcardId;
      this.dpr = uni.getSystemInfoSync().pixelRatio;
      this.sign = userinfo?.userName
      if (options.q) {
        const q = decodeURIComponent(options.q)
        let queryObj = getQueryVarible(q)

        this.postcardId = queryObj.postcardId
        this.userId = queryObj.userId;
      }
      if (!this.userId) {
        uni.showModal({
          showCancel: false,
          title: '提示',
          content: '还未登录，请登录',
          confirmText: '确认',
          success: (res) => {
            if (res.confirm) {
              uni.navigateTo({
                url: '/pages/login/login'
              })
            }
          }
        })
      }
      recorderManager.onStop((res) => {
        this.duration = res.duration;
        this.tempVoice = res.tempFilePath;
      })
      innerAudioContext.onPlay((res) => {
        console.log(res)
      })
      innerAudioContext.onEnded(res => {
        this.isPlaying = false;
        this.recordStatus = 2
      })
      if (this.modelcardId) {
        this.getCardDetail(this.modelcardId)
      }
      uni.$once('signature', this.handleSignature)
      this.getCanvas()
      wx.getPrivacySetting({
        success: res => {
          if (res.needAuthorization) {
            // 需要弹出隐私协议
            _this.privacyContractName = res.privacyContractName;
            _this.$refs.privacy.$refs.privacyPopup.open()
          }
        },
        fail: () => {},
        complete: () => {}
      })
    },
    methods: {
      gotoBack() {
        uni.switchTab({
          url: '/pages/index/index'
        })
      },
      handleSignature(signatureUrl) {
        this.writeImage = signatureUrl;
      },
      async onPreview() {
        if (!this.letterImage || this.letterImage.indexOf('http://tmp') > -1 || this.letterImage.indexOf(
            'wxfile://tmp') > -1) {
          this.letterImage = await this.buildContentImage()
        }
        this.$refs.previewPop.open()
      },
      async getRandomContent() {
        if (this.isComplete) {
          return
        }
        const res = await getContent()
        this.content = res.rows[0].content
      },
      checkSpecialChars(e) {
        let value = e.detail.value;
        this.$nextTick(() => {
          this.content = value.replace(/[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF]/g, '')
        })
      },
      getCanvas() {
        const query = wx.createSelectorQuery();
        query.select('#signature').fields({
            node: true,
            size: true
          })
          .exec(res => {
            this.canvas = res[0].node;
            this.ctx = this.canvas.getContext('2d')

            this.canvasWidth = res[0].width;
            this.canvasHeight = res[0].height;
            this.canvas.width = res[0].width * this.dpr;
            this.canvas.height = res[0].height * this.dpr
            this.ctx.scale(this.dpr, this.dpr)
            this.points = [];
            this.offscreenCanvas = uni.createOffscreenCanvas({
              type: '2d',
              width: this.canvas.width,
              height: this.canvas.height
            });
            this.offscreenCtx = this.offscreenCanvas.getContext('2d');
            this.drawimageToCavnas('http://xl-cover.kongetech.cn/3da2b02216eb200bc7e8ac93a9de689.png', 0, 0, this
              .offscreenCtx)
          })

      },
      touchstart(e) {
        let startX = e.changedTouches[0].x;
        let startY = e.changedTouches[0].y;
        this.beginPoint = {
          x: startX,
          y: startY
        }
        this.points.push({
          x: startX,
          y: startY
        })
        this.ctx.beginPath();
      },
      touchmove(e) {
        let movex = e.changedTouches[0].x;
        let movey = e.changedTouches[0].y;
        this.points.push({
          x: movex,
          y: movey
        })
        let len = this.points.length;
        const ctx = this.ctx;
        if (len > 3) {
          let lastTwoPoints = this.points.slice(-2)
          let controlPoint = lastTwoPoints[0]
          let endPoint = {
            x: (lastTwoPoints[0].x + lastTwoPoints[1].x) / 2,
            y: (lastTwoPoints[0].y + lastTwoPoints[1].y) / 2,
          }

          ctx.lineWidth = 1;
          ctx.lineCap = "round";
          ctx.lineJoin = "round"
          ctx.beginPath()
          ctx.moveTo(this.beginPoint.x, this.beginPoint.y)
          ctx.quadraticCurveTo(controlPoint.x, controlPoint.y, endPoint.x, endPoint.y)
          ctx.stroke()
          ctx.closePath()
          this.beginPoint = endPoint

        }
      },
      touchend(e) {
        this.points = []
      },
      onCheckboxChnage(e) {
        this.isOpen = e.detail.value.length > 0 ? 1 : 0
      },
      gotoUrl() {
        uni.navigateTo({
          url: '/pages/share/share?postcardId=' + this.postcardId + '&userId=' + this.userId
        })
      },
      nextStep() {
        if (this.cliperImg == "") {
          return;
        }
        const query = uni.createSelectorQuery()
        query.select('.upload-img-container').fields({
            size: true
          })
          .exec(res => {
            const obj = res[0]
            const height = obj.width * 2 / 3;
            this.height = height + 'px'
          })
        if (this.cardStatus == CARD_STATUS.UPLOAD_IMAGE) {
          this.cardStatus = CARD_STATUS.ENTER_MESSAGE
        } else {

          this.handleCardComplete()
        }
      },
      async updateUserPostcard(postData) {
        let result = await updateUserPostcard(postData)
        this.handlePostcardSuccess(result)
      },
      async createCustomPostcard(postData) {
        let result = await createCustomPostcard(postData)
        this.handlePostcardSuccess(result)
      },
      showDetail() {
        uni.navigateTo({
          url: '/pages/detail/detail?postcardId=' + this.postcardId
        })
      },
      async createReplyPostcard(replyUserId) {

        if (replyUserId) {
          let reply = await createReplyPostcard({
            userId: replyUserId,
            userPostcardId: this.postcardId
          })
          getApp().globalData.replyUserId = false;
        }
      },
      async handlePostcardSuccess(result) {
        this.isSending = false;
        this.$refs.previewPop.close()
        const replyUserId = getApp().globalData.replyUserId;
        if (result.code = 200) {
          if (result.id) {
            this.postcardId = result.id;
          }
          if (replyUserId) {
            this.createReplyPostcard(replyUserId)
          }
          uni.setStorageSync('cliperImg', this.cliperImg)
          uni.setStorageSync('sending', this.sending)
          this.isComplete = true;
          this.$showtoast('创建明信片成功')
        } else {
          this.$showtoast('创建明信片失败')
        }
      },
      getCanvasTempFilePath() {
        return uni.canvasToTempFilePath({
          canvas: this.canvas,
          destWidth: this.canvas.width,
          destHeight: this.canvas.height,
        })
      },
      createLetterImage(content, dy = 20, callFun) {
        const qrCodeWidth = 50;
        const {
          ctx,
          canvas,
          canvasWidth,
          canvasHeight
        } = this;
        let dx = 15;

        const contentArr = content.split('');
        const maxWidth = canvas.width - 60; //左右留10空白
        let line = ''

        ctx.font = '10px sans-serif'
        ctx.fillStyle = '#000000'
        ctx.texstBaseline = 'top'
        for (let n = 0; n < contentArr.length; n++) {
          var textline = line + contentArr[n];

          var matrics = ctx.measureText(textline);
          var testWidth = matrics.width * this.dpr;
          if (testWidth > maxWidth && n > 0) {
            ctx.fillText(line, dx, dy)
            line = contentArr[n];
            dy += 15
            if (dy > canvasHeight - qrCodeWidth) {
              dx = 15 + qrCodeWidth
            }
          } else {
            line = textline
          }
        }
        ctx.fillText(line, dx, dy)
        callFun && callFun(dy)

      },
      drawimageToCavnas(filePath, dx = 10, dy = 10, ctx) {
        return new Promise((resolve, reject) => {
          const image = this.canvas.createImage()
          image.src = filePath;
          image.onload = () => {
            ctx.drawImage(image, 0, 0, image.width, image.height, dx, dy, Math.min(this.canvas.width, image
              .width), Math.min(this.canvas.height,
              image.height));
            resolve()
          }
        })

      },
      drawTitle(title, dx, dy) {
        const {
          ctx
        } = this;
        ctx.font = '10px sans-serif'
        ctx.fillStyle = '#000000'
        ctx.fillText(title, dx, dy)
      },
      //生成内容图片
      async buildContentImage() {

        if (this.inputType == 0 && !this.writeImage) { //是否有手写的信息
          this.writeImage = this.canvas.toDataURL()
        }
        this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
        this.offscreenCtx.clearRect(0, 0, this.canvas.width, this.canvas.height)
        await this.drawimageToCavnas('http://xl-cover.kongetech.cn/3da2b02216eb200bc7e8ac93a9de689.png', 0, 0, this
          .offscreenCtx)
        if (this.writeImage) {
          await this.drawimageToCavnas(this.writeImage, 0, 0, this.offscreenCtx)
        }

        this.ctx.drawImage(this.offscreenCanvas, 0, 0, this.canvasWidth, this.canvasHeight)
        let isPass = true;
        let signatureImg = ""
        let {
          sign,
          content,
          sending
        } = this;
        if (sending) {
          let result = await checkMsg(sending)
          if (result.data == true) {
            isPass = false
            this.$showtoast('TA的称呼含有非法词语，请重新输入')
            return
          }
          this.drawTitle(this.sending, 10, 20)
        }
        if (!isPass) {
          return;
        }
        if (sign) {
          let result = await checkMsg(sign)
          if (result.data == true) {
            isPass = false
            this.$showtoast('你的名字含有非法词语，请重新输入')
            return
          }
          this.ctx.font = '10px sans-serif'
          const textWidth = this.ctx.measureText(sign).width;
          this.drawTitle(sign, this.canvasWidth - textWidth - 10, this.canvasHeight - 20)
        }
        if (!isPass) {
          return;
        }
        if (content) {
          let result = await checkMsg(content)
          if (result.data == true) {
            isPass = false;
            this.$showtoast('输入内容含有非法词语，请重新输入')
            return
          }
          if (content.indexOf('\n')) {
            const contents = content.split('\n')
            let dy = this.sending ? 40 : 20;
            contents.forEach(content => {
              this.createLetterImage(content, dy, (newDy) => {
                dy = newDy + 20;
              })

            })
          } else {
            this.createLetterImage(content)
          }

        }
        if (!isPass) {
          return;
        }
        const [err, res] = await this.getCanvasTempFilePath();
        if (err) {
          this.$showtoast(err)
          return
        } else {
          signatureImg = res.tempFilePath
        }
        return signatureImg
      },
      //保存明信片
      async handleCardComplete() {
        if (this.isSending) {
          return;
        }
        this.isSending = true

        let {
          sending,
          sign,
          signatureImg,
          voicePath,
          content,
          cliperImg
        } = this;

        this.$showtoast('正在保存中', 15000)
        if (!this.letterImage) {
          this.letterImage = await this.buildContentImage()
        }
        const results = await Promise.allSettled([uploadQ(cliperImg), uploadSound(voicePath), uploadQ(this
          .letterImage)]);
        if (results[0].status == 'rejected' || results[1].status == 'rejected' || results[2].status ==
          'rejected') {
          this.cliperImg = ""
          this.cardStatus = CARD_STATUS.UPLOAD_IMAGE
          this.height = '200px'
          this.isSending = false;
          return;
        }
        let frontPostcardUrl = results[0]?.value || ""
        let signurl = results[2]?.value
        let soundUrl = results[1]?.value || ""
        this.letterImage = 'http://' + signurl;
        const postData = {
          userId: this.userId,
          inputType: this.inputType,
          times: this.duration,
          soundUrl: soundUrl,
          content: this.content,
          sending: this.sending,
          sign: this.sign,
          isOpen: this.isOpen,
          letterContentUrl: signurl,
          frontPostcardUrl: frontPostcardUrl,
          letterPostcardUrl: signurl,
          postcardType: 0 //0:横屏，1竖屏
        }
        if (this.modelcardId) {
          postData.postcardId = this.modelcardId
        }
        if (this.postcardId) {
          postData.id = this.postcardId;
          this.updateUserPostcard(postData)
        } else {
          this.createCustomPostcard(postData)
        }
      },
      async getCardDetail(carid) {
        let res = await getPostcardList({
          postcardId: carid
        })
        if (res.rows[0]) {
          this.postCardInfo = res.rows[0]
          this.cliperImg = 'http://' + this.postCardInfo.frontImgUrl
          this.defaultSoundUrl = res.rows[0].defaultSoundUrl
        }

        if (this.cliperImg) {
          this.height = 'auto'
        }
      },
      playBgm() {
        if (!this.isPlaying) {
          this.isPlaying = true;
          innerAudioContext.src = this.defaultSoundUrl;
          innerAudioContext.onCanplay(() => {
            innerAudioContext.play()
          })

        } else {
          this.isPlaying = false;
          innerAudioContext.pause()
        }
      },
      chooseImage() {
        const _this = this;
        const screenWidth = uni.getSystemInfoSync().windowWidth
        uni.chooseMedia({
          mediaType: ['image'],
          sizeType: ['original'],
          count: 1,
          success(res) {
            let tempFile = res.tempFiles[0];
            _this.uploadImg = tempFile.tempFilePath;
            uni.getImageInfo({
              src: tempFile.tempFilePath,
              success: (res) => {

                _this.imageWidth = Math.min(res.width, screenWidth * 2);
                _this.imageHeight = _this.imageWidth * 2 / 3;
                // _this.imageHeight = res.width > res.height ? _this.imageWidth * 2 / 3 : _this.imageWidth * 3 /
                //   2;
                _this.showClipper = true;

              }

            })

          }
        })
      },
      cliperSuccess({
        width,
        height,
        url
      }) {
        this.cliperImg = url;
        this.showClipper = false;
        this.height = 'auto'
      },
      showRecordPop() {
        this.$refs.recordPopup.open()
        let i = 5;
        this.$showtoast(`${i}秒后开始录制`)
        let timer = setInterval(() => {
          i--
          this.$showtoast(`${i}秒后开始录制`)
          if (i == 0) {
            clearInterval(timer)
            uni.hideToast()
            this.handleRecordBtn()

          }

        }, 1000)
        this.timer = timer;
      },
      startRecord() {
        recorderManager.start()
        let minute = 0;
        let tenminute = 60000
        this.timer = setInterval(() => {
          let present = minute / tenminute * 100;
          minute += 1000 / 16;
          this.style = `--percent:${present}%`
        }, 1000 / 16)
      },
      stopRecord() {
        recorderManager.stop();
        clearInterval(this.timer)
      },
      playVoice() {
        if (this.tempVoice) {
          innerAudioContext.src = this.tempVoice;
          innerAudioContext.play()
        }
      },
      closeRecordPopup() {
        this.stopRecord();
        this.recordStatus = 0;
        this.$refs.recordPopup.close()
      },
      useVoice() {
        this.recordStatus = 0;
        this.$refs.recordPopup.close()
        this.voicePath = this.tempVoice;
      },
      reRecord() {
        this.recordStatus = 1;
        this.startRecord()
      },
      handleRecordBtn() {
        let status = this.recordStatus;
        clearInterval(this.timer)
        if (status == 0) {
          this.recordStatus = 1;
          this.startRecord();
        } else if (status == 1) {
          this.recordStatus = 2;
          this.stopRecord();
        } else if (status == 2) {
          this.recordStatus = 3;
          this.playVoice()
        } else if (status == 3) {
          innerAudioContext.stop()
          this.recordStatus = 2
        }
      }
    }
  }
</script>

<style lang="scss">
  .fixed-bg {
    background: linear-gradient(to bottom, #b1e2df 30%, #c7ece9 35%, #f5f7f8 60%, #e3f3f2 86%, #ade2dd);
  }

  .make-card-containerm {
    position: absolute;
    height: 100%;
    width: 100%;

    .content {
      padding-top: 200rpx;
      display: flex;
      flex-direction: column;
      align-items: center;
      color: #4bc7bd;
      box-sizing: border-box;
    }
  }

  .card-edit-container {
    width: 600rpx;
    height: 900rpx;
    perspective: 1000;

    .car-item {
      width: 600rpx;
      padding: 20rpx;
      position: absolute;
      top: 0;
      left: 0;
      transition: all .3s;
      backface-visibility: hidden;
      background: #fff;
      border-radius: 20rpx;
      box-sizing: border-box;
    }

    .enter-message-container {
      transform: rotateY(-180deg);
      overflow: hidden;
    }

    .texture-container {
      width: 100%;
      line-height: 30px;

      textarea {
        margin: 30rpx 0;
        width: 100%;
        height: 180px;
        font-size: 24rpx;
        background: repeating-linear-gradient(to top, #e0d9d9, #e0d9d9 1px, transparent 1px, transparent 30px);
        border-top: 1px solid #e0d9d9;
      }
    }
  }

  .upload-img,
  .message-bg {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    font-size: 18px;
    background: url('');
    background-size: 100% 100%;
  }

  .message-bg {
    align-items: flex-start;
    padding: 40rpx;
    box-sizing: border-box;
  }

  .input-container {
    width: 100%;
    display: flex;
  }

  .input-container:last-child {
    justify-content: flex-end;
  }

  .upload-img-container .record-btn {
    height: 100rpx;
    width: 100rpx;
    position: relative;
    margin-top: -80rpx;
  }

  .upload-img-container .record-btn>view {
    width: 100%;
    height: 100%;
  }

  .upload-img-container .record-btn image {
    width: 50%;
    height: 50%;
  }

  .upload-img-container .recording::after {
    width: 98rpx;
    height: 98rpx;
  }

  .showMessage .enter-message-container {
    transform: rotateY(0deg);
  }

  .showMessage .upload-img-container {
    transform: rotateY(-180deg);
  }

  .keep-make {
    margin: 20rpx auto;
    height: 75rpx;
    width: 230rpx;
    background-color: #6cd7cd;
    text-align: center;
    border-radius: 30px;
    line-height: 75rpx;
    color: #fff;
  }

  .keep-make.disabled {
    filter: saturate(0.8);
  }

  .op-content {
    padding: 0 40rpx;
    margin-top: -40px;
    display: flex;
    justify-content: space-between;
  }

  .enter-message-container {
    display: flex;
    flex-direction: column;
    justify-content: space-between;

    input {
      font-size: 32rpx;
      color: #6cd7cd;
      border-bottom: 1px solid;
      display: inline-block;
    }

    .message-content-container {
      margin-top: 20rpx;
      flex: 1;
      width: 100%;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
    }

  }

  .record-container {
    position: relative;
    padding-top: 50rpx;
    height: 300px;
    display: flex;
    justify-content: space-around;
    align-items: baseline;
    background-color: #fff;
    border-radius: 10px 10px 0 0;
    box-sizing: border-box;
    background-image: url();
    background-size: 100% 102rpx;
    background-position: bottom;
    background-repeat: no-repeat;
  }

  .close-icon {
    position: absolute;
    top: 10px;
    right: 10px;
  }

  .side-btn {
    width: 120rpx;
    height: 120rpx;
    font-size: 16px;
    text-align: center;
  }

  .record-btn-container {
    text-align: center;
  }

  .record-container {
    color: #4bc7bd;
    font-size: 18px;

    image {
      width: 40%;
      height: 100rpx;
    }
  }

  .record-btn {
    width: 160rpx;
    height: 160rpx;
    display: flex;
    justify-content: center;
    align-items: center;
    background-color: #4bc7bd;
    border-radius: 50%;
    margin: 30rpx auto;

  }

  .record-btn>view {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 150rpx;
    height: 150rpx;
    background-color: #4bc7bd;
    border-radius: 50%;
    position: relative;
    z-index: 2;
  }

  .active {
    color: #4bc7bd;
  }

  .cavnas-container {
    width: 100%;
    height: 150px;
    position: absolute;
    top: 0;
    z-index: 10;
    transform: translateX(-200%);
  }

  .cavnas-container.show {
    transform: translateX(0);
  }

  .preview-content {
    margin: 0 auto;
    width: 90%;
    padding: 20rpx;
    border-radius: 20rpx;
    background-color: #fff;
    text-align: center;
  }

  .write-canvas {
    background: url(http://xl-cover.kongetech.cn/3da2b02216eb200bc7e8ac93a9de689.png);
  }

  .write-canvas::after {
    content: '';
    width: 30px;
    height: 30px;
    position: absolute;
    bottom: 16rpx;
    left: 16rpx;
    border: 2px solid #4d4a4a;
    border-style: dashed;
  }
</style>